﻿/*
This file is part of Claymore.
Copyright (C) 2009, Fabrice Michellonet (fabrice dot michellonet at gmail dot com)

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
*/

using System;
using System.Reflection;
using System.Web;
using System.Web.UI;

namespace Claymore.Web
{
    public class ClaymoreHttpModule : IHttpModule
    {

        private const string CREATE_PRESENTER_METHOD_NAME = "CreatePresenterFor";

        #region Fields

        private HttpApplication _application;

        #endregion

        /// <summary>
        /// Initializes a module and prepares it to handle requests.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
        public void Init(HttpApplication context)
        {
            if(context == null)
                throw  new ArgumentNullException("context");

            _application = context;

            context.PostMapRequestHandler += onPostMapRequestHandler;
        }


        /// <summary>
        /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
        /// </summary>
        public void Dispose(){}

        /// <summary>
        /// Handle PostMapRequest event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void onPostMapRequestHandler(object sender, EventArgs e)
        {
            Page pageHandler;
            if ((pageHandler = _application.Context.Handler as Page) != null)
                pageHandler.PreInit += HandlePreInit;
        }

        /// <summary>
        /// Handles the pre init event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        protected virtual void HandlePreInit(object sender, EventArgs e)
        {
            Page page = sender as Page;
            if (page != null && typeof(IView).IsAssignableFrom(page.GetType())){
                foreach (Type type in page.GetType().BaseType.GetInterfaces())
                {
                    if (typeof(IView).IsAssignableFrom(type))
                    {
                        MethodInfo method = Claymore.PresenterManager.GetType().GetMethod(CREATE_PRESENTER_METHOD_NAME);
                        MethodInfo generic = method.MakeGenericMethod(type);
                        generic.Invoke(Claymore.PresenterManager, new object[]{page});
                    }
                }
            }
        }
    }
}